Shadow mapping or shadowing projection is a process by which are added to 3D computer graphics. This concept was introduced by Lance Williams in 1978, in a paper entitled "Casting curved shadows on curved surfaces."
Shadows are created by testing whether a pixel is visible from the light source, by comparing the pixel to a z-buffering or depth image of the light source's view, stored in the form of a texture mapping.
This technique is less accurate than , but the shadow map can be a faster alternative depending on how much fill time is required for either technique in a particular application and therefore may be more suitable to real-time applications. In addition, shadow maps do not require the use of an additional stencil buffer and can be modified to produce shadows with a soft edge. Unlike shadow volumes, however, the accuracy of a shadow map is limited by its resolution.
From this rendering, the depth buffer is extracted and saved. Because only the depth information is relevant, it is common to avoid updating the color buffers and disable all lighting and texture calculations for this rendering, to save drawing time. This depth map is often stored as a texture in graphics memory.
This depth map must be updated any time there are changes to either the light or the objects in the scene, but can be reused in other situations, such as those where only the viewing camera moves. (If there are multiple lights, a separate depth map must be used for each light.)
In many implementations, it is practical to render only a subset of the objects in the scene to the shadow map to save some of the time it takes to redraw the map. Also, a depth offset which shifts the objects away from the light may be applied to the shadow map rendering in an attempt to resolve Z-fighting problems where the depth map value is close to the depth of a surface being drawn (i.e., the shadow-casting surface) in the next step. Alternatively, culling front faces and only rendering the back of objects to the shadow map is sometimes used for a similar result.
The matrix used to transform the world coordinates into the light's viewing coordinates is the same as the one used to render the shadow map in the first step (under OpenGL this is the product of the model, view and projection matrices). This will produce a set of homogeneous coordinates that need a perspective division ( see 3D projection) to become normalized device coordinates, in which each component ( x, y, or z) falls between −1 and 1 (if it is visible from the light view). Many implementations (such as OpenGL and Direct3D) require an additional scale and bias matrix multiplication to map those −1 to 1 values to 0 to 1, which are more usual coordinates for depth map (texture map) lookup. This scaling can be done before the perspective division, and is easily folded into the previous transformation calculation by multiplying that matrix with the following:
If done with a shader, or other graphics hardware extension, this transformation is usually applied at the vertex level, and the generated value is interpolated between other vertices and passed to the fragment level.
If the z value is greater than the value stored in the depth map at the appropriate ( x, y) location, the object is considered to be behind an occluding object and should be marked as a failure, to be drawn in shadow by the drawing process. Otherwise, it should be drawn lit.
If the ( x, y) location falls outside the depth map, the programmer must either decide that the surface should be lit or shadowed by default (usually lit).
In a shader implementation, this test would be done at the fragment level. Also, care needs to be taken when selecting the type of texture map storage to be used by the hardware: if interpolation cannot be done, the shadow will appear to have a sharp, jagged edge (an effect that can be reduced with greater shadow map resolution).
It is possible to modify the depth map test to produce shadows with a soft edge by using a range of values (based on the proximity to the edge of the shadow) rather than simply pass or fail.
The shadow mapping technique can also be modified to draw a texture onto the lit regions, simulating the effect of a Video projector. The picture above captioned "visualization of the depth map projected onto the scene" is an example of such a process.
If shaders are not available, performing the depth map test must usually be implemented by some hardware extension (such as GL_ARB_shadow), which usually does not allow a choice between two lighting models (lit and shadowed), and necessitate more rendering passes:
The example pictures in this article used the OpenGL extension GL_ARB_shadow_ambient to accomplish the shadow map process in two passes.
Trapezoidal Shadow Maps,
Light Space Perspective Shadow maps,
or Parallel-Split Shadow maps.
Also notable is that generated shadows, even if aliasing free, have hard edges, which is not always desirable. In order to emulate real world soft shadows, several solutions have been developed, either by doing several lookups on the shadow map, generating geometry meant to emulate the soft edge or creating non-standard depth shadow maps. Notable examples of these are Percentage Closer Filtering, Smoothies, and Variance Shadow maps.
|
|